<template>
  <div class="card content-box">
    <el-upload ref="upload" class="upload-demo" action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
               :limit="1" :on-change="handleFileChange" :auto-upload="false">
      <template #trigger>
        <el-button type="primary">选择文件</el-button>
      </template>
      <el-button :disabled="uploadDisabled" class="ml-3" type="success" @click="handlerUpload">上传</el-button>
      <el-button class="ml-3" type="success" @click="handlePause">暂停</el-button>
      <el-button class="ml-3" type="success" @click="handleResume">恢复</el-button>
      <el-button class="ml-3" type="success" @click="resetData">重置</el-button>
      <template #tip>
        <br/><br/>
        <span>计算文件hash进度： {{ Math.round(state.current/state.total*100) }}%</span>
        <br/><br/>
        <span>上传进度：{{ percentage }}%</span>
        <el-progress type="circle" :percentage="percentage" :color="colors" />
        <el-progress :text-inside="true" :stroke-width="26" :percentage="100"/>
        <div class="el-upload__tip text-red">限制一个文件, 新文件将会覆盖原文件</div>
      </template>
    </el-upload>
  </div>
</template>
<script setup>
import uploadConstant from '@/constant/upload.js'
import {computed, reactive, ref} from "vue";
import SparkMD5 from 'spark-md5'
import * as util from '@/api/util/util.js'
import {mergeChunk, uploadChunk} from "@/api/backend/file/upload.js";
import {getFileMD5} from "@/api/util/util.js";

const upload = ref()
const state=reactive({
    uploadStatus:uploadConstant.UploadStatus.wait,
    chunkSize:uploadConstant.fileChunkSize,
    total:1,
    current:1,
    fileMD5:"",
    chunkList:[],
    successCount:0,
    requestChunkList:[],
    requestFnList:[],
    uploadFile:{},
    suffix:""
  })


const clearState=()=>{
  state.total=1
  state.current=1
  state.fileMD5=""
  state.chunkList=[]
  state.successCount=0
  state.requestChunkList=[]
  state.requestFnList=[]
  state.suffix=""
}
const colors = [
  { color: '#f56c6c', percentage: 20 },
  { color: '#e6a23c', percentage: 40 },
  { color: '#5cb87a', percentage: 60 },
  { color: '#1989fa', percentage: 80 },
  { color: '#6f7ad3', percentage: 100 },
]

  const uploadDisabled=computed(()=>state.uploadStatus===uploadConstant.UploadStatus.pause||state.uploadStatus===uploadConstant.UploadStatus.uploading)

  const percentage=computed(()=>{
    const result=Math.round(state.successCount/state.requestFnList.length*100)
    return  isNaN(result)?0:result
  })

  const handlePause=()=>{

  }

  const handleResume=()=>{

  }


  const resetData=()=>{

  }


  const  handleFileChange= (file,files)=>{
    const fileRaw=file.raw

     state.uploadFile=file
  }
  const handlerUpload=async ()=>{

    const rawFile=state.uploadFile.raw

    clearState()

    state.fileMD5=await getFileMD5(rawFile)

    state.suffix = /\.([0-9a-zA-Z]+)$/i.exec(rawFile.name)[1];

    await createChunkList(rawFile)

    createRequestList()

    doUpload()

  }

  const createChunkList=async (file)=>{
    let cur = 0
    state.total=Math.ceil(file.size/state.chunkSize)
    state.current=0
    console.log(state.total)
    while (cur < file.size) {
      const chunk=file.slice(cur, cur + state.chunkSize)

      //let buffer = await util.fileParse(chunk, "buffer")

      // const spark = new SparkMD5.ArrayBuffer()
      // spark.append(buffer);
      //
      // let md5 = spark.end();
      state.chunkList.push({
        file: chunk,
        md5:state.fileMD5
      })
      state.current++

      cur += state.chunkSize
    }

  }


  const createRequestList=()=>{
   state.requestFnList = state.chunkList.map((chunkItem,index)=>{
     const fn=() => {
       const formData = new FormData()
       formData.append("chunk", chunkItem.file)
       return uploadChunk(state.fileMD5, index,formData).catch(err=>{
        console.log(err)
       }).then(res=>{
         state.successCount++
         return res
       })
     }
     return fn
    })
  }

  const doUpload=()=>{
    const arr=[]
    state.requestFnList.forEach(requestFn=>{
        arr.push(requestFn())
    })

    Promise.all(arr).then(result=>{
      if(result.length===arr.length){
        mergeChunk(state.fileMD5,state.requestFnList.length,state.suffix).then(res=>{
          console.log()
        })
      }

      console.log(result)
    })
  }
</script>



<script>
export default {
  name: "GuiguUpload"
}
</script>


<style scoped>

</style>
